﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace SerialPortLibrary
{

    internal class DataBuffer : DataPublish, IDataBuffer
    {
        private ManualResetEvent ReceiveSign = new ManualResetEvent(false);
        private Thread thread;
        private List<byte> Buffer = new List<byte>();
        internal DataBuffer(IDataPublish publish)
        {
            publish.DataPublishEvent += DataPublish;
            this.Start();
        }

        private bool DataPublish(object sender, DataPublishEventArgs e)
        {
            serialdata = e.data;
            if (serialdata.Error.ErrorType == 0)
            {
                Monitor.Enter(Buffer);
                Buffer.AddRange(serialdata.Data);
                Monitor.Exit(Buffer);
                ReceiveSign.Set();
            }
            else if (serialdata.Error.ErrorType == -1)
            {
                Buffer.Clear();
            }
            else
            {
                OnDataPublishEvent(e);
            }
            return true;
        }

        private void DataReceive()
        {
            while (true)
            {
                ReceiveSign.WaitOne();
                //处理过程中有下一个数据入队；
                //如果数据不完整，会处于死循环状态；
                //while (Buffer.Count > 0)
                //{
                byte[] by = Buffer.ToArray();
                serialdata.Data = by;
                DataPublishEventArgs e = new DataPublishEventArgs(serialdata);
                if (OnDataPublishEvent(e))
                {
                    Buffer.RemoveRange(0, by.Length);
                }
                //}
                ReceiveSign.Reset();
            }
        }

        private void Start()
        {
            thread = new Thread(() => DataReceive());
            thread.Start();
        }

        private void Stop()
        {
            if (thread != null && thread.ThreadState == ThreadState.Running)
            {
                try
                {
                    thread.Abort();
                }
                catch
                {

                }
            }
        }

        public void Clear()
        {
            Buffer.Clear();
        }
    }
}
